package com.fattyCorps.service;

import com.fattyCorps.an.AEventListener;
import com.fattyCorps.cache.PlayerCache;
import com.fattyCorps.cache.packet.PacketMap;
import com.fattyCorps.config.gameConfig.GlobalConfig;
import com.fattyCorps.config.gameConfig.ItemConfig;
import com.fattyCorps.exception.gameException.item.*;
import com.fattyCorps.mgr.event.EEvent;
import com.fattyCorps.obj.cache.PlayerInfo;
import com.fattyCorps.obj.cache.player.packet.Item;
import com.fattyCorps.obj.mould.ItemMould;
import com.fattyCorps.obj.msg.SRet;
import com.fattyCorps.obj.msg.server.item.SGetItemListMsg;
import com.fattyCorps.obj.msg.server.item.SUseItemMsg;
import lombok.Data;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.util.List;

@Service
@Slf4j
public class ItemService {

    @Autowired
    PlayerCache playerCache;

    @Autowired
    ItemConfig itemConfig;

    @Autowired
    HeroService heroService;

    @Autowired
    PlayerService playerService;

    @Autowired
    GlobalConfig globalConfig;

    // 创建角色时初始化用户身上的道具
    @AEventListener(EEvent.EVENT_ON_PLAYER_CREATE)
    public void onPlayerCreate(PlayerInfo playerInfo) {
        String initItemsStr = globalConfig.getStringValue(GlobalConfig.PLAYER_INIT_ITEMS);
        String[] split = initItemsStr.split(",");

        for (int i=0; i<split.length; i++){
            Integer itemTypeID = Integer.valueOf(split[i]);
            i = i + 1;
            Integer itemNum = Integer.valueOf(split[i]);

            // 增加道具
            Item item = Item.makeItem(itemConfig, itemTypeID, itemNum);
            playerInfo.getPlayerData().getItems().put(item);
        }
    }

    // 获取道具列表
    public SRet getItemList(Integer playerId){
        PlayerInfo playerInfo = playerCache.getPlayerInfo(playerId);
        List<Item> items = playerInfo.getPlayerData().getItems().getElems();
        SGetItemListMsg sGetItemListMsg = new SGetItemListMsg();
        sGetItemListMsg.setItemList(items);
        return SRet.success(sGetItemListMsg);
    }

    // 使用道具
    public SRet useItem(Integer playerId, Integer itemId, Integer num){
        if(num<=0){
            throw new ItemNumErrorException();
        }

        Item item = getItem(playerId, itemId);
        ItemMould itemMould = itemConfig.getItemMould(item.getTypeId());
        switch (itemMould.getType()){
            case ItemConfig.ITEM_TYPE_HERO_FRAGMENT: {
                // 英雄碎片
                Integer heroTypeId = Integer.valueOf(itemMould.getProp());
                Integer oneHeroFragmentNum = globalConfig.getIntValue(GlobalConfig.ONE_HERO_FRAGMENT_NUM);
                if (num%oneHeroFragmentNum!=0){
                    throw new ItemNumErrorException();
                }
                int heroNum = num / oneHeroFragmentNum;

                // 删除道具
                boolean b = delItem(item, num);
                if (b){
                    // 创建英雄
                    for (int i=0; i<heroNum; i++){
                        heroService.createHero(playerId, heroTypeId);
                    }
                }else{
                    // 道具数量不足
                    throw new ItemNotEnoughErrorException();
                }
                break;
            }
            case ItemConfig.ITEM_TYPE_HERO_COIN: {
                // 元宝
                Integer coinNum = Integer.valueOf(itemMould.getProp());
                // 删除道具
                boolean b = delItem(item, num);
                if (b){
                    playerService.addCoin(playerId, coinNum*num);
                }else{
                    // 道具数量不足
                    throw new ItemNotEnoughErrorException();
                }
                break;
            }
            case ItemConfig.ITEM_TYPE_HERO_IDLE_PRICE: {
                // 挂机奖励
                // todo: 等关卡模块实现后来做
                break;
            }
            default:
                // 普通道具
                throw new ItemCanNotUseErrorException();
        }

        // 返回道具最新的数量
        SUseItemMsg sUseItemMsg = new SUseItemMsg();
        sUseItemMsg.setNewNum(item.getNum());
        return SRet.success(sUseItemMsg);
    }

    // 创建道具
    public void addItem(Integer playerId, Integer itemTypeId, Integer num){
        Item item = getItemByTypeId(playerId, itemTypeId);
        if (item==null){
            // 用户身上没有该typeId的道具
            Item newItem = Item.makeItem(itemConfig, itemTypeId, num);

            // 再去内存中增加
            getPacketItem(playerId).put(newItem);
        }else {
            // 用户身上有该typeId的道具
            Integer newNum = item.getNum() + num;
            item.setNum(newNum);
        }
    }

    // 根据道具typeId删除道具
    public boolean delItemByTypeId(Integer playerId, Integer itemTypeId, Integer delNum){
        Item item = getItemByTypeId(playerId, itemTypeId);
        return delItem(item, delNum);
    }

    // 删除道具
    public boolean delItem(Integer playerId, Integer itemId, Integer delNum){
        Item item = getItem(playerId, itemId);
        return delItem(item, delNum);
    }

    // 删除道具
    public boolean delItem(Item item, Integer delNum){
        if (item.getNum()<delNum){
            // 道具数量不足
            return false;
        }else {
            int newNum = item.getNum() - delNum;
            item.setNum(newNum);
        }
        return true;
    }

    // 根据道具id获取道具信息
    public Item getItem(Integer playerId, Integer itemId){
        return getPacketItem(playerId).get(itemId);
    }

    // 根据道具typeId获取道具信息
    public Item getItemByTypeId(Integer playerId, Integer itemTypeId){
        return getItemByTypeId(playerId, itemTypeId, true);
    }

    public Item getItemByTypeId(Integer playerId, Integer itemTypeId, boolean t){
        List<Item> items = getPacketItem(playerId).getElems();
        for (int i=0; i<items.size(); i++){
            Item item = items.get(i);
            if (item.getTypeId().equals(itemTypeId)){
                return item;
            }
        }

        if (t) {
            throw new ItemNotEnoughErrorException();
        }

        return null;
    }

    public PacketMap<Item> getPacketItem(Integer playerId) {
        return playerCache.getPlayerInfo(playerId).getPlayerData().getItems();
    }

    @Data
    public class ItemElem {
        private Integer typeId;
        private Integer num;
    }
}
